2026 年宋诏桥小学 C++ 联赛第一轮完整题解(三年级)
原帖发布于洛谷,故附件下载需要登录洛谷。
题解作者:hetao4025037
该比赛于 2026 年 3 月 23 日 12:00 正式开始,至 2026 年 3 月 23 日 13:00 完全结束(总时长 1 小时)。该比赛共 4 题,单题总分均为 100 分,共 400 分。
0. 作者声明
本人非比赛参赛选手,题目顺序由三年级第一名选手(shimuyang1024)提供,题解公开于洛谷。若有侵权,请告知(洛谷私信)删除。
1. 题目目录
提示:点击题目名称,可跳转到对应题目。
T1 B2008 计算 (a+b)×c 的值
T2 B2060 满足条件的数累加
T3 B2044 有一门课不及格的学生
T4 B2067 药房管理
2. 题目详解
T1:B2008 计算 (A+B)×C 的值
本题极为入门,不作详细解释,只需要注意一点:
C++ 中的乘号(×\times×),需要使用 *。
本题无需考虑数据超出 int 类型的问题,因为输出最大也只会达到 2×1082\times10^82×108。
完整代码(AC 代码):
T2:B2060 满足条件的数累加
题目大意
统计 [m,n][m,n][m,n] 范围内 171717 的倍数之和。
解题思路 & 完整代码
我们可以定义一个变量:
* ans:计数器 / 答案变量,存储范围 m∼nm\sim nm∼n 内,所有 171717 的倍数的累加和。
方法一:
使用暴力循环 m∼nm\sim nm∼n,每次判断该数是否为 171717 的倍数,存入答案变量。
for 循环写法:
循环体内的代码:
完整代码(AC 代码):
方法二:
通过 方法一 的分析,不难发现,方法一 的代码过于暴力,要遍历 n−m+1n-m+1n−m+1 次,还需要大量的判断,特别耗时!对此,我们可以进行优化。
我们都知道:相邻的 171717 的倍数之间的差值都是 171717。根据这个特性,我们可以把 for 循环的 i++ 改为 i += 17。但是我们不能保证循环变量的起始值(上述代码中为 mmm)是 171717 的倍数,我们必须把循环变量的起始值改为 大于等于 mmm 最小的 171717 的倍数(下文用 kkk 表示)。
kkk 可以使用 公式法 / 线性查找 的方法来获取。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
公式法
(能被 171717 整除的数可统一写成:k=17tk=17tk=17t,ttt 为正整数。)
要求 17t≥m17t\ge m17t≥m,变形得
t≥m17t\ge\frac{m}{17} t≥17m
满足不等式的最小整数 ttt 为对 m17\dfrac{m}{17}17m 向上取整
t=⌈m17⌉t=\left\lceil\frac{m}{17}\right\rceil t=⌈17m ⌉
因此最小倍数
k=17×⌈m17⌉k=17\times\left\lceil\frac{m}{17}\right\rceil k=17×⌈17m ⌉
注意:C++ 自身的整数除法操作为向下取整
(1) 使用向上取整转向下取整的数学结论(不会的自行上网“补课”哦)
⌈ab⌉=⌊a+b−1b⌋\left\lceil\frac{a}{b}\right\rceil=\left\lfloor\frac{a+b-1}{b}\right\rfloor ⌈ba ⌉=⌊ba+b−1 ⌋
代入数据,可得
k=17×⌈m17⌉=17×⌊m−1617⌋k=17\times\left\lceil\frac{m}{17}\right\rceil=17\times\left\lfloor\frac{m-16}{17}\right\rfloor k=17×⌈17m ⌉=17×⌊17m−16 ⌋
转为 C++ 代码:
(2) double 类型配合 <cmath> 库中的 ceil() 函数
接上文公式,我们可以用 m / 17.0 来取到小数值,再配合上 ceil() 函数:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
线性查找
从 mmm 开始(包括 mmm),依次向后检查,直到这个数是 171717 的倍数(即找到目标数 kkk),这个循环最多会执行 171717 次。
核心代码:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
完整代码(AC 代码):
方法三:
方法二 与 方法一 相比,已经快了不少。
但代码还能继续优化吗?
答案是肯定的!
延续 方法二 的思路,[m,n][m,n][m,n] 范围内所有 171717 的倍数可以构成一个等差数列!
根据等差数列求和公式(不会的自行上网“补课”哦)
(首项+末项)×项数2\frac{(首项+末项)\times项数}{2} 2(首项+末项)×项数
可知,我们还缺两个关键的值:末项 & 项数
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
末项求解 【不超过 nnn 的最大的 171717 的倍数(下文用 bbb 表示)】
(能被 171717 整除的数可统一写成:k=17tk=17tk=17t,ttt 为正整数。)
要求 17t≤n17t\le n17t≤n,变形得
t≤n17t\le\frac{n}{17} t≤17n
满足不等式的最大整数 ttt 为对 n17\frac{n}{17}17n 向下取整
t=⌊n17⌋t=\left\lfloor\frac{n}{17}\right\rfloor t=⌊17n ⌋
因此最大倍数
b=17×⌊n17⌋b=17\times\left\lfloor\frac{n}{17}\right\rfloor b=17×⌊17n ⌋
注意:C++ 自身的整数除法操作为向下取整,与 b=17×⌊n17⌋b=17\times\left\lfloor\frac{n}{17}\right\rfloorb=17×⌊17n ⌋ 中的向下取整完全一致!
直接转为 C++ 代码:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
项数求解(下文用 ttt 代替)
设首项为 kkk,末项为 bbb,公差为 171717,项数记作 ttt。
数列通项关系:
b=k+(t−1)×17b=k+(t−1)\times17 b=k+(t−1)×17
式子变形推导:
b=k+(t−1)×17(t−1)×17=b−kt−1=b−k17t=b−k17+1\begin{align*} b &= k + (t-1)\times 17 \\ (t-1)\times 17 &= b - k \\ t-1 &= \frac{b-k}{17} \\ t &= \frac{b-k}{17} + 1 \end{align*} b(t−1)×17t−1t =k+(t−1)×17=b−k=17b−k =17b−k +1
k,bk,bk,b 均为 171717 的倍数,差值可整除,对应代码:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
最终求和公式
ans=(k+b)×t2ans=\frac{(k+b)\times t}{2} ans=2(k+b)×t
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
完整代码(AC 代码):
三种方法对比
对比维度 方法一 方法二 方法三 核心思路 遍历区间全数,判断倍数累加 定位首项,步长 171717 遍历倍数累加 等差数列公式直接求值 时间复杂度 O(n)O(n)O(n) O(n)O(n)O(n) O(1)O(1)O(1) 空间复杂度 O(1)O(1)O(1) O(1)O(1)O(1) O(1)O(1)O(1) 代码难度 简单易懂 轻量数学推导 需数学推导 本题推荐度 ★★★☆☆ ★★★★★ ★★★★☆ 备注 / 时间复杂度省略 求 kkk 的代码 /
T3:B2044 有一门课不及格的学生
题目大意
已知一名学生的语文、数学、英语三科成绩,判断这个学生是不是三科中恰好有一门学科不及格(<60<60<60)。
解题思路 & 完整代码
本题有较多方法求解,本文将取用其中两种较常用方法进行讲解。
我们首先定义一个变量:
* cnt:计数器,存储不及格科目的数量。
方法一:
每次输入后,进行判断:是否不及格(<60<60<60)。如果不及格,就累加 111(cnt++;):
最后判断 cnt 是否正好为 1:
完整代码(AC 代码):
方法二:
根据 bool 类型转 int 类型的特性:
* true->1
* false->0
我们不难发现,它正好符合上文中要求:如果不及格,就累加 111(引出:如果及格,就累加 000)。
这里的 1,01,01,0 正好就是 bool 类型转 int 类型的数值。
我们就可以把代码改成:
完整代码(AC 代码):
两种方法对比
对比维度 方法一 方法二 核心思路 分支判断统计不及格科目数 布尔运算隐式计数累加 时间复杂度 O(1)O(1)O(1) O(1)O(1)O(1) 空间复杂度 O(1)O(1)O(1) O(1)O(1)O(1) 代码难度 简单易懂 简洁精炼 本题推荐度 ★★★★☆ ★★★★★
T4:B2067 药房管理
题目大意
给定初始药量 mmm 与取药人数 nnn,依次接收每位病人取药量。药量充足则扣除对应数量,不足则判定取药失败,统计并输出失败总人数。
解题思路 & 完整代码
本题可以采用模拟法来解决。
我们可以定义两个变量:
* ans:计数器 / 答案变量,存储没取到药的人数。
首先,循环处理 nnn 位病人的取药请求:
* 若病人需要的数量 ≤\le≤ 当前库存:扣除药品,取药成功。
* 若病人需要的数量 >>> 当前库存:无法取药,失败人数 +1+1+1(ans++;)。
最后输出没取到药的总人数。
完整代码(AC 代码)
3. 比赛总结
本次比赛整体难度较低,内容较为基础。
个人主观难度评价:★☆☆☆☆
*附
PDF 附件:
2026 年 宋诏桥小学 C++ 联赛第一轮完整题解(三年级).pdf(PDF 版题解不包含附件 & 附链接)